package com.binc.testspring.study.design.observer;

import java.util.Arrays;
import java.util.Observable;
import java.util.Observer;

/**
 * FileName: TestObserver  观察者模式的拓展， 抽象的观察者 和 抽象的被观察者都是用的jdk的东西，不再是自行抽象了
 *
 * 这里推荐用抽象类 而不是说接口了
 *
 * 关键点就是在被观察的对象里聚合一个 观察者的集合，有需要通知观察者的时候，遍历这个集合，然后挨个调用观者的方法；
 *
 * Autho: binC
 * Date:  2022/3/31 19:03
 */
public class TestObserver_EX {

    public static void main(String[] args) {
         Weixin weixin = new Weixin();
        Ali ali = new Ali();

        ConcreteSubject2 sub = new ConcreteSubject2(); //创建被观察者对象
        sub.addObserver(weixin); // 这里是注册观察者
        sub.addObserver(ali);

        sub.subjectDo_1();
        System.out.println("==========");
        sub.subjectDo_2();
    }

}

//被观察者的抽象，这里不在掺杂观察者操作的代码了，关于观察者的操作都在Observable中了
interface  MySubject {
    void subjectDo_1();
    void subjectDo_2();
}


// 具体的被观察者者1    具体的主题   关键实现Obervable接口
class ConcreteSubject2 extends  Observable implements MySubject{

    /********下面是抽象类的抽象方法，需要具体被观察者去重写的*********/
    @Override
    public void subjectDo_1() {
        System.out.println("被观察者执行了方法1....");
        super.setChanged();
        super.notifyObservers("1");//调用父类方法，通知所有的观察者们
    }
    @Override
    public void subjectDo_2() {
        System.out.println("被观察者执行了方法22222....");
        super.setChanged();
        super.notifyObservers("2");//调用父类方法，通知所有的观察者们
    }
}


/**************************************/


//具体观察者1
class Weixin implements java.util.Observer {

    public void obDoSomething(Object... objects) {
        System.out.println("微信观察者得到通知了,参数是【"+ Arrays.toString(objects)+"】");
    }

    /**
     * 每当观察到的对象发生变化时，都会调用此方法。应用程序调用 <tt>Observable<tt> 对象的 <code>notifyObservers<code> 方法来通知对象的所有观察者更改。
     * @param o   the observable object.
     * @param arg an argument passed to the <code>notifyObservers</code>
     */
    @Override
    public void update(Observable o, Object arg) {
        obDoSomething(arg);
    }
}

//具体观察者2
class Ali implements  java.util.Observer{

    public void obDoSomething(Object... objects) {
        System.out.println("阿里观察者得到通知了，参数是【"+ Arrays.toString(objects)+"】");
    }

    /**
     * 每当观察到的对象发生变化时，都会调用此方法。应用程序调用 <tt>Observable<tt> 对象的 <code>notifyObservers<code> 方法来通知对象的所有观察者更改。
     *
     * @param o   the observable object.
     * @param arg an argument passed to the <code>notifyObservers</code>
     */
    @Override
    public void update(Observable o, Object arg) {
        obDoSomething(arg);
    }
}

